/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** *****************************************************************************************************
 * \file     Mcu_Rstgen.c                                                                               *
 * \brief    AUTOSAR 4.3.1 MCAL Mcu Driver                                                              *
 *                                                                                                      *
 * <table>                                                                                              *
 * <tr><th>Date           <th>Version                                                                   *
 * <tr><td>2023/08/02     <td>1.0.0                                                                     *
 * </table>                                                                                             *
 *******************************************************************************************************/
/********************************************************************************************************
 *                                      Include header files                                            *
 *******************************************************************************************************/
#include "RegHelper.h"
#include "Mcu_GeneralTypes.h"
#include "Mcu_Rstgen.h"
#include "regs_base.h"
#include "Mcal_Scr.h"

/********************************************************************************************************
 *                                 Private Macro definition                                             *
 *******************************************************************************************************/
#define WA_SAFETY_SE_CORE_ID    (4U)
#define WA_PFU_CTRL_BYPASS      (1U << 1U)
#define WA_PFU_CTRL_SWITCH_DONE (1UL << 31U)

/********************************************************************************************************
 *                                 Private Type Definitions                                             *
 *******************************************************************************************************/
#define MRAM1_MODULE_RESET_ID  (79U)
#define MRAM4_MODULE_RESET_ID  (82U)
/********************************************************************************************************
 *                                  Private Constant Definitions                                        *
 *******************************************************************************************************/
/* PRQA S 3218 EOF */
/* workaround for AXISD unexpected sem error */
#define MCU_START_SEC_CONST_UNSPECIFIED
#include "Mcu_MemMap.h"
static const Mcal_ScrSignalType mram_i_axi_uncerr_en[4] = {
    SCR_SF_AXISD_MRAM1_I_AXI_UNCERR_EN,
    SCR_SF_AXISD_MRAM2_I_AXI_UNCERR_EN,
    SCR_SF_AXISD_MRAM3_I_AXI_UNCERR_EN,
    SCR_SF_AXISD_MRAM4_I_AXI_UNCERR_EN

};
static const Mcal_ScrSignalType mram_i_axi_sync_down_lkstep_comp_err_en[4] = {
    SCR_SF_AXISD_MRAM1_I_AXI_SYNC_DOWN_LKSTEP_COMP_ERR_EN,
    SCR_SF_AXISD_MRAM2_I_AXI_SYNC_DOWN_LKSTEP_COMP_ERR_EN,
    SCR_SF_AXISD_MRAM3_I_AXI_SYNC_DOWN_LKSTEP_COMP_ERR_EN,
    SCR_SF_AXISD_MRAM4_I_AXI_SYNC_DOWN_LKSTEP_COMP_ERR_EN

};
static const Mcal_ScrSignalType mram_i_axi_sync_down_unc_irq_en[4] = {
    SCR_SF_AXISD_MRAM1_I_AXI_SYNC_DOWN_UNC_IRQ_EN,
    SCR_SF_AXISD_MRAM2_I_AXI_SYNC_DOWN_UNC_IRQ_EN,
    SCR_SF_AXISD_MRAM3_I_AXI_SYNC_DOWN_UNC_IRQ_EN,
    SCR_SF_AXISD_MRAM4_I_AXI_SYNC_DOWN_UNC_IRQ_EN

};
static const Mcal_ScrSignalType mram_i_axi_uncerr_clr[4] = {
    SCR_SF_AXISD_MRAM1_I_AXI_UNCERR_CLR,
    SCR_SF_AXISD_MRAM2_I_AXI_UNCERR_CLR,
    SCR_SF_AXISD_MRAM3_I_AXI_UNCERR_CLR,
    SCR_SF_AXISD_MRAM4_I_AXI_UNCERR_CLR

};
static const Mcal_ScrSignalType mram_i_axi_sync_down_lkstep_comp_err_clr[4] = {
    SCR_SF_AXISD_MRAM1_I_AXI_SYNC_DOWN_LKSTEP_COMP_ERR_CLR,
    SCR_SF_AXISD_MRAM2_I_AXI_SYNC_DOWN_LKSTEP_COMP_ERR_CLR,
    SCR_SF_AXISD_MRAM3_I_AXI_SYNC_DOWN_LKSTEP_COMP_ERR_CLR,
    SCR_SF_AXISD_MRAM4_I_AXI_SYNC_DOWN_LKSTEP_COMP_ERR_CLR
};
#define MCU_STOP_SEC_CONST_UNSPECIFIED
#include "Mcu_MemMap.h"

/********************************************************************************************************
 *                                  Global Function Declarations                                        *
 *******************************************************************************************************/
#define MCU_START_SEC_CODE
#include "Mcu_MemMap.h"

/** *****************************************************************************************************
 * \brief rstgen core control
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_RstgenLldCoreControl(uint32 base, uint32 coreIdx, boolean en)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - RSTGEN base address.
 *                      coreIdx - core id
 *                      en - 0: off, 1: on
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : 0 if OK, or a error code.
 *
 * Description        : rstgen core control
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_RstgenLldCoreControl(uint32 base, uint32 coreIdx, boolean en)
{
    uint32 coreSwRst = (base + CORE_RESET_CONTROL_OFF(coreIdx));
    Std_ReturnType errStatus = E_OK;
    uint32 value;
    uint32 pfuBase = 0UL;
    uint32 pfuCtrl;

    if (FALSE == en)
    {
        /* workaround for Soc PFU */
        if (APB_RSTGEN_LP_BASE == base)
        {
            pfuBase = APB_PFU_LP_BASE;
        }
        else
        {
            if (WA_SAFETY_SE_CORE_ID == coreIdx)
            {
                pfuBase = APB_R5_SE_PFU_BASE;
            }
        }

        if (pfuBase != 0UL)
        {
            /* Change PFU mode to bypass mode. */
            pfuCtrl = readl(pfuBase);
            writel(pfuCtrl | WA_PFU_CTRL_BYPASS, pfuBase);

            /* pollin idle status */
            if (FALSE == Mcu_Ip_WaitForBitTimes(pfuBase, WA_PFU_CTRL_SWITCH_DONE,
                1U, RSTGEN_POLLs))
            {
                errStatus = MCU_E_TIMEOUT;
            }
        }

        /* Check core SW reset status */
        if (BM_CORE_RESET_CONTROL_RSTA == (readl(coreSwRst) & BM_CORE_RESET_CONTROL_RSTA))
        {
            /* Set core run mode. */
            value = readl(coreSwRst);
            value &= ~BM_CORE_RESET_CONTROL_RUN_MODE;
            writel(value, coreSwRst);

            /* Wait reset done. */
            if (FALSE == Mcu_Ip_WaitForBitTimes(coreSwRst, BM_CORE_RESET_CONTROL_RSTA,
                                                en, RSTGEN_POLLs))
            {
                errStatus = MCU_E_TIMEOUT;
            } /* else not needed */

        } /* else not needed */
    }
    else
    {
        /* Check core SW reset status */
        if (0U == (readl(coreSwRst) & BM_CORE_RESET_CONTROL_RSTA))
        {
            /* Set core run mode. */
            value = readl(coreSwRst);
            value |= BM_CORE_RESET_CONTROL_RUN_MODE;
            writel(value, coreSwRst);

            /* Wait reset done. */
            if (FALSE == Mcu_Ip_WaitForBitTimes(coreSwRst, BM_CORE_RESET_CONTROL_RSTA,
                                                en, RSTGEN_POLLs))
            {
                errStatus = MCU_E_TIMEOUT;
            } /* else not needed */

        } /* else not needed */
    }

    return errStatus;
}

/** *****************************************************************************************************
 * \brief rstgen core reset
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_RstgenLldCoreReset(uint32 base, uint32 coreIdx)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - RSTGEN base address.
 *                      coreIdx - core id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : 0 if OK, or a error code.
 *
 * Description        : rstgen core reset
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_RstgenLldCoreReset(uint32 base, uint32 coreIdx)
{
    uint32 coreRst = (base + CORE_RESET_CONTROL_OFF(coreIdx));
    Std_ReturnType errStatus = E_OK;

    uint32 pfuBase = 0UL;
    uint32 pfuCtrl;
    uint32 val = readl(coreRst);
    uint32 status = (val & BM_CORE_RESET_CONTROL_RSTA);

    /* workaround for Soc PFU */
    if (APB_RSTGEN_LP_BASE == base)
    {
        pfuBase = APB_PFU_LP_BASE;
    }
    else
    {
        if (WA_SAFETY_SE_CORE_ID == coreIdx)
        {
            pfuBase = APB_R5_SE_PFU_BASE;
        }
    }

    if (pfuBase != 0UL)
    {
        /* Change PFU mode to bypass mode. */
        pfuCtrl = readl(pfuBase);
        writel(pfuCtrl | WA_PFU_CTRL_BYPASS, pfuBase);

        /* pollin idle status */
        if (FALSE == Mcu_Ip_WaitForBitTimes(pfuBase, WA_PFU_CTRL_SWITCH_DONE,
            1U, RSTGEN_POLLs))
        {
            errStatus = MCU_E_TIMEOUT;
        }
    }

    if (0U != status)
    {
        /* Auto clear reset when the core is already running */
        writel(val | BM_CORE_RESET_CONTROL_AUTO_CLR_RST_B, coreRst);

        /* Trigger auto clear reset */
        if (FALSE == Mcu_Ip_WaitForBitTimes(coreRst, BM_CORE_RESET_CONTROL_AUTO_CLR_RST_B,
                                            0U, RSTGEN_POLLs))
        {
            errStatus = MCU_E_TIMEOUT;
        } /* else not needed */
    }
    else
    {
        /* Set running mode when the core is off */
        val |= BM_CORE_RESET_CONTROL_RUN_MODE;
        writel(val, coreRst);

        /* Trigger real time reset status */
        if (FALSE == Mcu_Ip_WaitForBitTimes(coreRst, BM_CORE_RESET_CONTROL_RSTA,
                                            1U, RSTGEN_POLLs))
        {
            errStatus = MCU_E_TIMEOUT;
        } /* else not needed */
    }

    return errStatus;
}

/** *****************************************************************************************************
 * \brief rstgen module control
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_RstgenLldModuleControl(uint32 base, uint32 moduleIdx, boolean en)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - RSTGEN base address.
 *                      moduleIdx - module index
 *                      en - 0:module off, 1:module on
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : 0 if OK, or a error code.
 *
 * Description        : rstgen module control
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_RstgenLldModuleControl(uint32 base, uint32 moduleIdx, boolean en)
{
    uint32 moduleRst = (base + MODULE_RESET_CONTROL_OFF(moduleIdx));
    uint32 val = readl(moduleRst);
    Std_ReturnType errStatus = E_OK;

    if (TRUE == en)
    {
        /* workaround for AXISD unexpected sem error */
        if ((moduleIdx >= MRAM1_MODULE_RESET_ID) && (moduleIdx <= MRAM4_MODULE_RESET_ID))
        {
            (void)Mcal_ScrSetBit(&mram_i_axi_uncerr_en[moduleIdx - MRAM1_MODULE_RESET_ID], 1U);
            (void)Mcal_ScrSetBit(&mram_i_axi_sync_down_lkstep_comp_err_en[moduleIdx - MRAM1_MODULE_RESET_ID], 1U);
            (void)Mcal_ScrSetBit(&mram_i_axi_sync_down_unc_irq_en[moduleIdx - MRAM1_MODULE_RESET_ID], 1U);
    
            (void)Mcal_ScrSetBit(&mram_i_axi_uncerr_clr[moduleIdx - MRAM1_MODULE_RESET_ID], 0U);
            (void)Mcal_ScrSetBit(&mram_i_axi_sync_down_lkstep_comp_err_clr[moduleIdx - MRAM1_MODULE_RESET_ID], 0U);
        }
        val |= BM_MODULE_RESET_CONTROL_RUN_MODE;
    }
    else
    {
        /* workaround for AXISD unexpected sem error */
        if ((moduleIdx >= MRAM1_MODULE_RESET_ID) && (moduleIdx <= MRAM4_MODULE_RESET_ID))
        {
            (void)Mcal_ScrSetBit(&mram_i_axi_uncerr_en[moduleIdx - MRAM1_MODULE_RESET_ID], 0U);
            (void)Mcal_ScrSetBit(&mram_i_axi_sync_down_lkstep_comp_err_en[moduleIdx - MRAM1_MODULE_RESET_ID], 0U);
            (void)Mcal_ScrSetBit(&mram_i_axi_sync_down_unc_irq_en[moduleIdx - MRAM1_MODULE_RESET_ID], 0U);
    
            (void)Mcal_ScrSetBit(&mram_i_axi_uncerr_clr[moduleIdx - MRAM1_MODULE_RESET_ID], 1U);
            (void)Mcal_ScrSetBit(&mram_i_axi_sync_down_lkstep_comp_err_clr[moduleIdx - MRAM1_MODULE_RESET_ID], 1U);
        }
        val &= ~BM_MODULE_RESET_CONTROL_RUN_MODE;
    }

    writel(val, moduleRst);

    if (FALSE == Mcu_Ip_WaitForBitTimes(moduleRst, BM_MODULE_RESET_CONTROL_RSTA,
                                        en, RSTGEN_POLLs))
    {
        errStatus = MCU_E_TIMEOUT;
    } /* else not needed */

    return errStatus;
}

/** *****************************************************************************************************
 * \brief rstgen mission control
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_RstgenLldMissionControl(uint32 base, uint32 missionIdx, boolean en)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - RSTGEN base address.
 *                      missionIdx - mission index
 *                      en - 0:misson off, 1:misson on
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : 0 if OK, or a error code.
 *
 * Description        : rstgen mission control
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_RstgenLldMissionControl(uint32 base, uint32 missionIdx, boolean en)
{
    uint32 missionRst = (base + MISSION_RESET_CONTROL_OFF(missionIdx));
    Std_ReturnType errStatus = E_OK;

    uint32 val = readl(missionRst);

    if (TRUE == en)
    {
        val |= BM_MISSION_RESET_CONTROL_RUN_MODE;
    }
    else
    {
        val &= ~BM_MISSION_RESET_CONTROL_RUN_MODE;
    }

    writel(val, missionRst);

    if (FALSE == Mcu_Ip_WaitForBitTimes(missionRst, BM_MISSION_RESET_CONTROL_RSTA,
                                        en, RSTGEN_POLLs))
    {
        errStatus = MCU_E_TIMEOUT;
    } /* else not needed */

    return errStatus;
}

/** *****************************************************************************************************
 * \brief rstgen debug control
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_RstgenLldDebugControl(uint32 base, boolean en)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - RSTGEN base address.
 *                      en - 0:debug off, 1:debug on
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : 0 if OK, or a error code.
 *
 * Description        : rstgen debug control
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_RstgenLldDebugControl(uint32 base, boolean en)
{
    uint32 debugRst = base + DBG_RESET_CONTROL_OFF;
    uint32 val = readl(debugRst);
    Std_ReturnType errStatus = E_OK;

    if (TRUE == en)
    {
        val |= BM_DBG_RESET_CONTROL_RUN_MODE;
    }
    else
    {
        val &= ~BM_DBG_RESET_CONTROL_RUN_MODE;
    }

    writel(val, debugRst);

    if (FALSE == Mcu_Ip_WaitForBitTimes(debugRst, BM_DBG_RESET_CONTROL_RSTA,
                                        en, RSTGEN_POLLs))
    {
        errStatus = MCU_E_TIMEOUT;
    } /* else not needed */

    return errStatus;
}

/** *****************************************************************************************************
 * \brief global reset
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_RstgenLldGlobalReset(uint32 sfBase)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : sfBase - RSTGEN base address.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : global reset, sf send sw global reset req, need lp set rst_req_en
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
void Mcu_Ip_RstgenLldGlobalReset(uint32 sfBase)
{
    uint32 val = readl(APB_RSTGEN_LP_BASE + GLOBAL_RESET_CONTROL_OFF);

    val &= ~FM_GLOBAL_RESET_CONTROL_RST_REQ_EN;
    val |= FV_GLOBAL_RESET_CONTROL_RST_REQ_EN(1U);
    writel(val, (APB_RSTGEN_LP_BASE + GLOBAL_RESET_CONTROL_OFF));

    val = readl(sfBase + GLOBAL_RESET_CONTROL_OFF);
    val |= BM_GLOBAL_RESET_CONTROL_SW_GLB_RST_EN;
    val |= BM_GLOBAL_RESET_CONTROL_SW_GLB_RST;

    writel(val, (sfBase + GLOBAL_RESET_CONTROL_OFF));
}

/** *****************************************************************************************************
 * \brief rstgen get core reset status
 *
 * \verbatim
 * Syntax             : boolean Mcu_Ip_RstgenLldGetCoreResetStatus(uint32 base, uint32 coreIdx)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - RSTGEN base address.
 *                      coreIdx - core index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : 1, the core reset has be released.
 *                      0, the core reset hasn't be released.
 *
 * Description        : rstgen get core reset status
 * \endverbatim
 *******************************************************************************************************/
boolean Mcu_Ip_RstgenLldGetCoreResetStatus(uint32 base, uint32 coreIdx)
{
    boolean isRelease;
    uint32 coreRst = (base + CORE_RESET_CONTROL_OFF(coreIdx));

    if (BM_CORE_RESET_CONTROL_RSTA == (readl(coreRst) & BM_CORE_RESET_CONTROL_RSTA))
    {
        isRelease = TRUE;
    }
    else
    {
        isRelease = FALSE;
    }

    return isRelease;
}

/** *****************************************************************************************************
 * \brief rstgen get module reset status
 *
 * \verbatim
 * Syntax             : boolean Mcu_Ip_RstgenLldGetModuleResetStatus(uint32 base, uint32 moduleIdx)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - RSTGEN base address.
 *                      moduleIdx - module index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : 1, the module reset has be released.
 *                      0, the module reset hasn't be released.
 *
 * Description        : rstgen get module reset status
 * \endverbatim
 *******************************************************************************************************/
boolean Mcu_Ip_RstgenLldGetModuleResetStatus(uint32 base, uint32 moduleIdx)
{
    boolean isRelease;
    uint32 moduleRst = (base + MODULE_RESET_CONTROL_OFF(moduleIdx));

    /* RSTGEN_MODULE_RST_STA, 0 = reset, 1 = release. */
    if (BM_MODULE_RESET_CONTROL_RSTA == (readl(moduleRst) & BM_MODULE_RESET_CONTROL_RSTA))
    {
        isRelease = TRUE;
    }
    else
    {
        isRelease = FALSE;
    }

    return isRelease;
}

/** *****************************************************************************************************
 * \brief rstgen get mission reset status
 *
 * \verbatim
 * Syntax             : boolean Mcu_Ip_RstgenLldGetMissionResetStatus(uint32 base, uint32 missionIdx)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - RSTGEN base address.
 *                      missionIdx - mission index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : 1, the mission reset has be released.
 *                      0, the mission reset hasn't be released.
 *
 * Description        : rstgen get mission reset status
 * \endverbatim
 *******************************************************************************************************/
boolean Mcu_Ip_RstgenLldGetMissionResetStatus(uint32 base, uint32 missionIdx)
{
    boolean isRelease;
    uint32 missionRst = (base + MISSION_RESET_CONTROL_OFF(missionIdx));

    /* RSTGEN_MODULE_RST_STA, 0 = reset, 1 = release. */
    if (BM_MISSION_RESET_CONTROL_RSTA == (readl(missionRst) & (BM_MISSION_RESET_CONTROL_RSTA)))
    {
        isRelease = TRUE;
    }
    else
    {
        isRelease = FALSE;
    }

    return isRelease;
}

/** *****************************************************************************************************
 * \brief rstgen get general reg value
 *
 * \verbatim
 * Syntax             : uint32 Mcu_Ip_RstgenLldReadGeneralReg(uint32 base, uint32 regIdx)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - RSTGEN base address.
 *                      regIdx - general register id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : general reg value
 *
 * Description        : rstgen get general reg value
 * \endverbatim
 *******************************************************************************************************/
uint32 Mcu_Ip_RstgenLldReadGeneralReg(uint32 base, uint32 regIdx)
{
    return (readl(base + GENERAL_REG_OFF(regIdx)));
}

/** *****************************************************************************************************
 * \brief rstgen write general reg value
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_RstgenLldWriteGeneralReg(uint32 base, uint32 regIdx, uint32 val)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - RSTGEN base address.
 *                      regIdx - general register id
 *                      val - value to write
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : This function Write general register value.
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_RstgenLldWriteGeneralReg(uint32 base, uint32 regIdx, uint32 val)
{
    writel(val, (base + GENERAL_REG_OFF(regIdx)));
}


/** *****************************************************************************************************
 * \brief This function write global reset mask.
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_RstgenRgGlbResetEn(uint32 base, uint32 msk)
 *
 * Service ID[hex]    : none
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - rstgen base
 *                      msk - value to write
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : This function write global reset mask.
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_RstgenRgGlbResetEn(uint32 base, uint32 msk)
{
    uint32 v = readl(base + GLOBAL_RESET_CONTROL_OFF);
    v |= msk;
    writel(v, base + GLOBAL_RESET_CONTROL_OFF);
}

/** *****************************************************************************************************
 * \brief read the reset type from the hardware register
 *
 * \verbatim
 * Syntax             : Mcu_RawResetType Mcu_Ip_GetResetRawValue(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - RSTGEN base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : Reset raw value
 *
 * Description        : read the reset type from the hardware register
 * \endverbatim
 *******************************************************************************************************/
Mcu_RawResetType Mcu_Ip_GetResetRawValue(uint32 base)
{
    Mcu_RawResetType value = readl(base + GLOBAL_RESET_STA_OFF);
    return value;
}

/** *****************************************************************************************************
 * \brief get reset type
 *
 * \verbatim
 * Syntax             : Mcu_ResetType Mcu_Ip_GetResetReason(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : None
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : reset type
 *
 * Description        : get reset type
 * \endverbatim
 *******************************************************************************************************/
Mcu_ResetType Mcu_Ip_GetResetReason(uint32 base)
{
    uint32 value = (uint32)Mcu_Ip_GetResetRawValue(base);
    uint32 valueLp = (uint32)Mcu_Ip_GetResetRawValue(APB_RSTGEN_LP_BASE);
    Mcu_ResetType resetType;

    /* #30  get reset reason*/
    if ((0U == value) && (0U == valueLp))
    {
        resetType = MCU_POWER_ON_RESET;
    }
    else if ((value & 0x01U) > 0U)                      /* pvt reset */
    {
        resetType = MCU_PVT_RESET;
    }
    else if ((value & ((uint32)0x01U << 2U)) > 0U)      /* sem reset */
    {
        resetType = MCU_SEM_RESET;
    }
    else if ((value & ((uint32)0x01U << 3U)) > 0U)      /* voltage detect reset */
    {
        resetType = MCU_VDC_RESET;
    }
    else if ((value & ((uint32)0x01U << 4U)) > 0U)      /* efuse non valiadate reset */
    {
        resetType = MCU_EFUSE_RESET;
    }
    else if ((value & ((uint32)0x01U << 10U)) > 0U)      /* sf_sw_glb reset */
    {
        resetType = MCU_SW_RESET;
    }
    else if ((value & ((uint32)0x1FU << 12U)) > 0U)
    {
        /* bit[16:12] wdt reset:
        * bit16:wdt2
        * bit15:wdt6
        * bit14:wdt5
        * bit13:wdt4
        * bit12:wdt3
        */
        resetType = MCU_WATCHDOG_RESET;
    }
    else
    {
        resetType = MCU_RESET_UNDEFINED;
    }

    return resetType;
}


#define MCU_STOP_SEC_CODE
#include "Mcu_MemMap.h"
/* End of file */
